package com.rybbaby.tss.core.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rybbaby.tss.core.utils.pojo.DateMorpherEx;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.JSONUtils;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author 谢进伟
 * @description json处理工具
 * @createDate 2016年2月15日 上午9:11:56
 */
public class JSONUtil {

    private static ObjectMapper om = new ObjectMapper();

    /**
     * 将一个对象格式化成json串
     *
     * @param obj 需要格式化的对象, 当需要格式化的对象中包含日期类型的时候，默认格式化形式：yyyy-MM-dd HH:mm:ss
     * @return
     * @throws JsonProcessingException
     */
    public static String toJsonStr(Object obj) throws JsonProcessingException {
        om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));// 设置日期类型格式化形式
        return om.writeValueAsString(obj);
    }

    /**
     * 将一个对象格式化成json串
     *
     * @param obj                  需要格式化的对象
     * @param dateFormatterPattern 当需要格式化的对象中包含日期类型的时候，时间格式化形式
     * @return
     * @throws JsonProcessingException
     */
    public static String toJsonStr(Object obj, String dateFormatterPattern) throws JsonProcessingException {
        if (StringUtils.isBlank(dateFormatterPattern)) {
            return toJsonStr(obj);
        }
        om.setDateFormat(new SimpleDateFormat(dateFormatterPattern));
        return om.writeValueAsString(obj);
    }

    /**
     * 将一个json串转换成一个pojo对象
     *
     * @param jsonStr json串
     * @param cls     pojo类型
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T jsonToBean(String jsonStr, Class<T> cls) {
        try {
            JSONObject jsonObject = JSONObject.fromObject(jsonStr);
            Object obj = jsonToBean(jsonObject, cls);
            return (T) obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将一个json对象转换成一个pojo对象
     *
     * @param
     * @param cls     pojo类型
     * @return
     */
    @SuppressWarnings("unchecked")
    public static <T> T jsonToBean(JSONObject json, Class<T> cls) {
        try {
            JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpherEx(new String[]{"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd", "yyyy-MM-dd't'HH:mm:ss"}, (Date) null));//调用DateMorpherEx，defaultValue为null
            Object obj = JSONObject.toBean(json, cls);
            return (T) obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将一个json对象转换成一个pojo对象
     *
     * @param
     * @param jsonConfig 转换配置
     * @param <T>
     * @return
     */
    public static <T> T jsonToBean(String jsonStr, JsonConfig jsonConfig) {
        try {
            JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpherEx(new String[]{"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd", "yyyy-MM-dd't'HH:mm:ss"}, (Date) null));//调用DateMorpherEx，defaultValue为null
            Object obj = JSONObject.toBean(JSONObject.fromObject(jsonStr), jsonConfig);
            return (T) obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将一个json对象转换成一个pojo对象
     *
     * @param json       jsonObject 对象
     * @param jsonConfig 转换配置
     * @param <T>
     * @return
     */
    public static <T> T jsonToBean(JSONObject json, JsonConfig jsonConfig) {
        try {
            JSONUtils.getMorpherRegistry().registerMorpher(new DateMorpherEx(new String[]{"yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd", "yyyy-MM-dd't'HH:mm:ss"}, (Date) null));//调用DateMorpherEx，defaultValue为null
            Object obj = JSONObject.toBean(json, jsonConfig);
            return (T) obj;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * json 转集合
     *
     * @param jsonString json字符串
     * @param classT     类型
     * @return
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    public static <T> List<T> jsonToList(String jsonString, Class<T> classT) throws InstantiationException, IllegalAccessException {
        JsonConfig jsonConfig = new JsonConfig();
        return toList(jsonString, classT, jsonConfig);
    }

    /**
     * json 转集合
     *
     * @param jsonString json字符串
     * @param classMap   类型映射
     * @param classT     类型
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    public static <T> List<T> jsonToList(String jsonString, Map<String, Class<?>> classMap, Class<T> classT) throws InstantiationException, IllegalAccessException {
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setClassMap(classMap);
        return toList(jsonString, classT, jsonConfig);
    }

    @SuppressWarnings("unchecked")
    private static <T> List<T> toList(String jsonString, Class<T> classT, JsonConfig jsonConfig) throws InstantiationException, IllegalAccessException {
        JSONArray jsonArray = JSONArray.fromObject(jsonString);
        return JSONArray.toList(jsonArray, classT.newInstance(), jsonConfig);
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static Object getVal(JSONObject obj, String key) {
        if (obj.containsKey(key)) {
            return obj.get(key);
        } else {
            return null;
        }
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static int getIntVal(JSONObject obj, String key) {
        try {
            return obj.getInt(key);
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static Integer getInteger(JSONObject obj, String key) {
        try {
            return obj.getInt(key);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static Long getLong(JSONObject obj, String key) {
        try {
            return obj.getLong(key);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static long getLongVal(JSONObject obj, String key) {
        try {
            return obj.getLong(key);
        } catch (Exception e) {
            return 0L;
        }
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static double getDoubleVal(JSONObject obj, String key) {
        try {
            return obj.getDouble(key);
        } catch (Exception e) {
            return 0D;
        }
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static Double getDouble(JSONObject obj, String key) {
        try {
            return obj.getDouble(key);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static boolean getBooleanVal(JSONObject obj, String key) {
        try {
            return obj.getBoolean(key);
        } catch (Exception e) {
            return false;
        }
    }
    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static Boolean getBoolean(JSONObject obj, String key) {
        try {
            return obj.getBoolean(key);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取json对象中指定key的值
     *
     * @param obj json对象
     * @param key key
     * @return
     */
    public static String getStringVal(JSONObject obj, String key) {
        if (obj.containsKey(key)) {
            return obj.getString(key);
        } else {
            return null;
        }
    }
}
